import pandas as pd
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter

def fill_data_to_template(source_file, template_file, output_file, sheet_name=None):
    """
    将源表格数据按列名填入模板表格，保持模板样式不变
    
    参数:
    source_file: 源Excel文件路径
    template_file: 模板Excel文件路径（包含样式）
    output_file: 输出Excel文件路径
    sheet_name: 工作表名称（如果为None，则使用第一个工作表）
    """
    # 读取源数据
    try:
        source_df = pd.read_excel(source_file)
    except Exception as e:
        raise ValueError(f"无法读取源文件 {source_file}: {str(e)}")
    
    # 加载模板工作簿（保留样式）
    try:
        wb = load_workbook(template_file)
    except Exception as e:
        raise ValueError(f"无法加载模板文件 {template_file}: {str(e)}")
    
    # 选择工作表
    if sheet_name is None:
        ws = wb.active
    else:
        if sheet_name in wb.sheetnames:
            ws = wb[sheet_name]
        else:
            raise ValueError(f"工作表 {sheet_name} 不存在于模板文件中")
    
    # 获取模板中的列名（假设第一行是标题）
    template_columns = []
    for cell in ws[1]:
        template_columns.append(cell.value)
    
    # 保存样式信息
    # 保存列宽
    column_widths = {}
    for col_letter in range(1, ws.max_column + 1):
        col_letter_str = get_column_letter(col_letter)
        column_widths[col_letter_str] = ws.column_dimensions[col_letter_str].width
    
    # 保存行高（标题行）
    header_row_height = ws.row_dimensions[1].height
    
    # 清除模板中除标题外的数据，但保留样式
    max_row = ws.max_row
    for row_idx in range(2, max_row + 1):
        for col_idx in range(1, ws.max_column + 1):
            cell = ws.cell(row=row_idx, column=col_idx)
            cell.value = None
    
    # 按列名匹配并填充数据
    for idx, row in source_df.iterrows():
        for col_idx, col_name in enumerate(template_columns, 1):
            if col_name in source_df.columns:
                target_row = idx + 2
                cell = ws.cell(row=target_row, column=col_idx)
                cell.value = row[col_name]
    
    # 恢复列宽
    for col_letter, width in column_widths.items():
        ws.column_dimensions[col_letter].width = width
    
    # 恢复标题行高
    ws.row_dimensions[1].height = header_row_height
    
    # 调整数据行高
    for row_idx in range(2, target_row + 1):
        ws.row_dimensions[row_idx].height = header_row_height
    
    # 保存结果
    try:
        wb.save(output_file)
    except Exception as e:
        raise IOError(f"无法保存到 {output_file}: {str(e)}")

# 示例用法
if __name__ == "__main__":
    source_file = r"D:\wxzx\4G5G资料20220610\2025\20251011\5GAAU存量表20251011.xlsx"
    template_file = r"D:\wxzx\数据修改模板-空.xlsx"
    output_file = r"D:\wxzx\output.xlsx"
    sheet_name = "AAU"  # 可选参数
    
    try:
        fill_data_to_template(source_file, template_file, output_file,sheet_name)
        print(f"数据已成功填入模板并保存到 {output_file}")
    except Exception as e:
        print(f"处理过程中出错: {str(e)}")